home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 March: Reference Library / Dev.CD Mar 97 RL.toast / mac / Technical Documentation / Macintosh Technical Notes / technotes / tn / 1076_MsgTest.hqx / MsgTest / PCMsgTst / PCMSGTST.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-29  |  8.1 KB  |  259 lines

  1. // --------------------------------------------------------------------------------------
  2. //
  3. // Test.c
  4. // By Ben Manuto
  5. //
  6. // A Simple application to receive and send a SInt16 message via the Message system API.
  7. // Must be built with large model.
  8. //
  9. // c.1996, by Apple Computer, Inc. All rights reserved.
  10. //
  11. // --------------------------------------------------------------------------------------
  12.  
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <malloc.h>
  17. #include <conio.h>
  18. #include "PCMsgTst.h"
  19.  
  20. #define kDefaultCmdType        0x6D736774          // 'msgt' - Our msg command OSType
  21. #define kDefaultMsgSize        256                 // Our message packet will be 256 bytes.
  22. #define kDefaultMsgTypes    2                    // We will register 2 cmd types for 'msgt'
  23.  
  24. SInt16 gCompCalled;
  25. SInt16 gAckReceived;         
  26.  
  27.  
  28. // ----------------------------------------------------------------------------------------
  29.  
  30. SInt32 WaitMsg(MsgPBlkPtr theMsg)
  31. {
  32. SInt32 i=0;
  33.  
  34.     while ((theMsg->msgResult == 1) && (!(kbhit())));
  35.     
  36.     if (theMsg->msgResult) {                     // Did we get a recieve error?
  37.         printf("\n\nWaitMsg():Rcv Error = %i\n", theMsg->msgResult);
  38.         return theMsg->msgResult;
  39.     }
  40.    
  41.    return theMsg->msgParam1;
  42. }
  43.  
  44.  
  45. // ----------------------------------------------------------------------------------------
  46.  
  47. void __loadds RcvCompletion(void)
  48. {
  49.     gCompCalled = true;
  50. }
  51.  
  52.  
  53. // ----------------------------------------------------------------------------------------
  54.  
  55. void __loadds SendCompletion(void)
  56. {
  57.     gCompCalled = true;
  58. }
  59.     
  60.  
  61. // ----------------------------------------------------------------------------------------
  62.  
  63. void __loadds InitMsg(MsgPBlkPtr theMsg, SInt32 bytes, SInt32 completionRtn)
  64. {
  65.     theMsg->msgFlags = 0;
  66.     theMsg->msgReqCount = bytes;
  67.     theMsg->msgActCount = 0;
  68.     theMsg->msgCompletion = completionRtn;
  69.     theMsg->msgResult = 1;
  70.  
  71.     gCompCalled = false;
  72. }
  73.  
  74.  
  75. // ----------------------------------------------------------------------------------------
  76.  
  77. SInt16 SendAck(SInt16 cmdBase, SInt32 bytesReceived)
  78. {
  79. MsgPBlkPtr ackMessage;
  80. SInt16 key;
  81.  
  82.     ackMessage = _fmalloc(sizeof(MsgPBlk));             // Allocate space for the ackMessage PBlk.
  83.     
  84.     ackMessage->msgCmd = cmdBase+1;                        // Set the message type as an ack.
  85.     ackMessage->msgParam1 = bytesReceived;                // param1 is the bytes received.
  86.     ackMessage->msgParam2 = 0L;
  87.     ackMessage->msgBuffer = 0L;
  88.     
  89.     InitMsg(ackMessage, 0, (SInt32) SendCompletion);        // Init the common variable and set the completion rtn.
  90.     MsgSend(ackMessage);                                  // Send the ackMessage
  91.     
  92.     key = 0;
  93.     printf("Ack Sent......");
  94.     while ((gCompCalled == false) && (key ==0)) {        // Wait for the receive completion routine to be called.
  95.         key = kbhit();
  96.     }
  97.  
  98.     _ffree(ackMessage);
  99.     
  100.     if (key != 0) {
  101.         printf("ack completion aborted!\n");
  102.         return(-1);
  103.     }
  104.     else {
  105.         printf("ack completion called.\n");
  106.         return(0);
  107.     }
  108.                        
  109. }
  110.  
  111.  
  112. // ----------------------------------------------------------------------------------------
  113.  
  114. SInt16 WaitForAck(AckInfo *theAck)
  115. {
  116. SInt16 key, bytes = kDefaultMsgSize;
  117.  
  118.     key = 0;
  119.     printf("Waiting for Ack......");
  120.     while ((theAck->ackReceived == false) && (key ==0)) {        // Wait for the receive completion routine to be called.
  121.         key = kbhit();
  122.     }
  123.  
  124.     if (key != 0) {
  125.         printf("Wait aborted!\n");
  126.         return(-1);
  127.     }
  128.     else {
  129.         printf("Ack Received.\n");
  130.         
  131.         if (theAck->bytesReceived == (SInt32) bytes)
  132.             printf("Message sent successfully. All %d bytes received by Mac.\n", bytes);
  133.         else
  134.             printf("The message was not received properly. %d bytes were sent and %d were received by the Mac.\n",
  135.                     bytes, theAck->bytesReceived);
  136.                     
  137.         return(0);
  138.     }
  139. }
  140.  
  141.  
  142. // ----------------------------------------------------------------------------------------
  143.  
  144. void main() 
  145. {
  146. MsgPBlkPtr aMessage;
  147. MsgRecElemPtr theMsgRec;
  148. AckInfo theAck;
  149. SInt16 err, cmdBase, i;
  150. SInt32 SInt32Err;
  151. SInt8 key;
  152.  
  153.     err = MsgAvailable();                               // Is the messaging system available?
  154.     printf("msgAvailable err: %04X\n",err);
  155.    
  156.     err = MsgRegister(kDefaultCmdType, 
  157.                       kDefaultMsgTypes, 
  158.                       &cmdBase);                        // Register our Command type.
  159.     printf("MsgRegister err: %04X cmmd: %4X\n\n", 
  160.                 err, cmdBase);
  161.     
  162.     theAck.bytesReceived = 0;                              // Init the ack info.
  163.     theAck.ackReceived = false;
  164.     
  165.     theMsgRec = _fmalloc(sizeof(MsgRecElem));            // allocate space for the receiver block.
  166.                        
  167.     theMsgRec->Link        = 0x00;                            // Ptr to next link
  168.     theMsgRec->Code        = (SInt32) MsgHandler;              // Ptr to the Code for this link
  169.     theMsgRec->cmdBase    = cmdBase;                        // the base message number for this proc
  170.     theMsgRec->cmdCount    = kDefaultMsgTypes;             // the # of message numbers for this proc
  171.     theMsgRec->userData    = (SInt32) &theAck;                // store a pointer to our ackInfo.
  172.     theMsgRec->recVXD    = 0x00;
  173.  
  174.     
  175.     aMessage = _fmalloc(sizeof(MsgPBlk));                // Allocate space for the send block.
  176.  
  177.     aMessage->msgCmd = cmdBase;                            // Init up the MsgPBlk....
  178.     aMessage->msgParam1 = 0x12345678;                    // just for fun...
  179.     aMessage->msgParam2 = kDefaultMsgSize;              // set param2 to buffer size (not required)
  180.     aMessage->msgBuffer = _fmalloc(kDefaultMsgSize);    // Allocate space for our buffer.
  181.     
  182.     
  183.     if (aMessage->msgBuffer == 0L) {                       // Make sure our buffer got allocated.
  184.         printf("\nBuffer was not allocated!!\n");
  185.           exit(1);
  186.       }
  187.     
  188.     MsgInstHandler(theMsgRec);                            // Install our message handler.
  189.     printf("\nHandler installed\n");
  190.    
  191.     printf("Initializing message...\n");
  192.     InitMsg(aMessage, 
  193.             kDefaultMsgSize, 
  194.             (SInt32) RcvCompletion);                     // Init our MsgPBlk.
  195.         
  196.     err = MsgReceive(aMessage);                            // Queue up our receiving MsgPBlk.
  197.         
  198.     printf("Waiting for Message....\n");               
  199.     SInt32Err = WaitMsg(aMessage);                      // Wait unitl MsgPBlk is no SInt32er busy.
  200.     
  201.     aMessage->msgBuffer -= kDefaultMsgSize;                // Set back the buffer pointer.
  202.     
  203.     printf("\nRequested Bytes = %ld,  Actual Bytes = %ld\n", 
  204.                 aMessage->msgReqCount, aMessage->msgActCount);
  205.     printf("Param1 = $%08lX = #%li     Param2 = $%08lX = #%li\n", 
  206.                 aMessage->msgParam1, aMessage->msgParam1,
  207.                 aMessage->msgParam2, aMessage->msgParam2);
  208.     
  209.     for (i = 0; i < kDefaultMsgSize; i++) {                  // Print the msgBuffer.
  210.         printf("%2X ", (UInt8) ((aMessage->msgBuffer)[i]));
  211.         if (((i+1) % 16) == 0) printf("\n");
  212.     }
  213.     
  214.     printf("\nWaiting for Rcv completion routine to be called....\n");
  215.     
  216.     key = 0;
  217.     while ((gCompCalled == false) && (key ==0)) {            // Wait for the receive completion routine to be called.
  218.         key = kbhit();
  219.     }
  220.     if (key != 0) goto Exit;
  221.     printf("Rcv completion routine Called!\n\n");
  222.     
  223.     err = SendAck(cmdBase, aMessage->msgActCount);             // Send an Ack to the Mac.
  224.     if (err) goto Exit;
  225.     
  226.     for (i = 0; i < kDefaultMsgSize; i++) {                 // Reverse the data in the buffer.
  227.         (aMessage->msgBuffer)[i] = (SInt8) (kDefaultMsgSize - i - 1);
  228.     }
  229.     
  230.     InitMsg(aMessage, 
  231.             kDefaultMsgSize, 
  232.             (SInt32)SendCompletion);                         // Init a new MsgPBlk to send.
  233.     
  234.     gAckReceived = false;                                    // Set the ackReceived flag false.
  235.     
  236.     MsgSend(aMessage);                                      // Send the new PBlk.
  237.     
  238.     printf("Waiting for Send completion routine to be called....\n");
  239.     
  240.     key = 0;
  241.     while ((gCompCalled == false) && (key ==0)) {             // Wait for the completion routine to be called.
  242.         key = kbhit();
  243.     }
  244.     if (key != 0) goto Exit;
  245.     printf("Send completion routine Called!\n");
  246.     
  247.     err = WaitForAck(&theAck);                                // Wait for response from Mac.
  248.     
  249.     Exit:
  250.         err = MsgRmvHandler(theMsgRec);                     // Remove the message handler
  251.         printf("\nHandler removed. Err = %d\n", err);
  252.             
  253.         _ffree(aMessage->msgBuffer);                           // Free up the buffer space.
  254.         _ffree(aMessage);
  255.         _ffree(theMsgRec);
  256. }
  257.  
  258.                                                           
  259.